/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide.explorer.view; import java.awt.dnd.*; import java.awt.Point; import java.awt.datatransfer.*; import javax.swing.JTree; import javax.swing.tree.TreePath; import javax.swing.tree.TreeCellEditor; import javax.swing.SwingUtilities; import org.openide.TopManager; import org.openide.nodes.Node; import org.openide.nodes.NodeTransfer; import org.openide.util.datatransfer.PasteType; import org.openide.util.datatransfer.ExTransferable; import org.openide.util.NbBundle; import org.openide.util.RequestProcessor; /** Implementation of drop support for asociated Tree View. * * @author Dafe Simonek */ final class TreeViewDropSupport implements DropTargetListener, Runnable { // Attributes /** true if support is active, false otherwise */ boolean active = false; /** Drop target asociated with the tree */ DropTarget dropTarget; /** The path to last node above which we were during * DnD operation. */ TreePath lastPath; // Associations /** View manager. */ protected TreeView view; /** The component we are supporting with drop support */ protected JTree tree; // Operations /** Creates new TreeViewDropSupport */ public TreeViewDropSupport (TreeView view, JTree tree) { this.view = view; this.tree = tree; } /** User is starting to drag over us */ public void dragEnter (DropTargetDragEvent dtde) { //System.out.println("Drag enter...."); // NOI18N TreePath tp = getTreePath(dtde); if (tp == null) { dtde.rejectDrag(); } else { dtde.acceptDrag(dtde.getDropAction()); lastPath = tp; NodeRenderer.dragEnter(tp.getLastPathComponent()); tree.paintImmediately(tree.getPathBounds(tp)); } } /** User drags over us */ public void dragOver (DropTargetDragEvent dtde) { TreePath tp = getTreePath(dtde); if (tp == null) { //System.out.println("REjecting..."); // NOI18N dtde.rejectDrag(); if (lastPath != null) { NodeRenderer.dragExit(); tree.repaint(tree.getPathBounds(lastPath)); lastPath = null; } } else { //System.out.println("Accepting..."); // NOI18N dtde.acceptDrag(dtde.getDropAction()); if ((lastPath != null) && (!lastPath.equals(tp))) { NodeRenderer.dragExit(); tree.repaint(tree.getPathBounds(lastPath)); } if (!tp.equals(lastPath)) { NodeRenderer.dragEnter(tp.getLastPathComponent()); tree.repaint(tree.getPathBounds(tp)); lastPath = tp; } } } public void dropActionChanged (DropTargetDragEvent dtde) { //System.out.println("Changing drop action..."); // NOI18N // PENDING...? } /** User exits the dragging */ public void dragExit (DropTargetEvent dte) { if (lastPath != null) { NodeRenderer.dragExit(); tree.repaint(tree.getPathBounds(lastPath)); lastPath = null; } } /** Performs the drop action, if we are dropping on * right node and target node agrees. */ public void drop (DropTargetDropEvent dtde) { //System.out.println("Dropping!!!"); // NOI18N // obtain the node we have cursor on Point location = dtde.getLocation(); TreePath tp = tree.getPathForLocation(location.x, location.y); Object obj = null; // return if conditions are not satisfied int dropAction = dtde.getDropAction(); if ((tp == null) || ((dropAction & view.getAllowedDropActions()) == 0) || !((obj = tp.getLastPathComponent()) instanceof Node)) { dtde.rejectDrop(); return; } // get paste types for given transferred transferable PasteType[] pt = DragDropUtilities.getPasteTypes((Node)obj, dtde.getTransferable()); if ((pt == null) || (pt.length <= 0)) { // notify user dtde.dropComplete(false); // caused deadlocks, so commented... //RequestProcessor.postRequest(this, 500); return; } // finally perform the drop dtde.acceptDrop(dropAction); if (dropAction == DnDConstants.ACTION_LINK) { // show popup menu to the user // PENDING } else { DragDropUtilities.performDrop(pt[0]); } // notify tree cell editor that DnD operation has ended // ??? it's here because source.dragDropEnd is not called // when accepting drop TreeCellEditor tce = tree.getCellEditor(); if (tce instanceof TreeViewCellEditor) ((TreeViewCellEditor)tce).setDnDActive(false); // finished dtde.dropComplete(true); } /** Activates or deactivates Drag support on asociated JTree * component * @param active true if the support should be active, false * otherwise */ public void activate (boolean active) { if (this.active == active) return; this.active = active; getDropTarget().setActive(active); } /** Implementation of the runnable interface. * Notifies user in AWT thread. */ public void run () { SwingUtilities.invokeLater( new Runnable () { public void run () { DragDropUtilities.dropNotSuccesfull(); } } ); } /** @return The tree path to the node the cursor is above now or * null if no such node currently exists or if conditions were not * satisfied to continue with DnD operation. */ TreePath getTreePath (DropTargetDragEvent dtde) { int dropAction = dtde.getDropAction(); // check actions if ((dropAction & view.getAllowedDropActions()) == 0) return null; // check location Point location = dtde.getLocation(); TreePath tp = tree.getPathForLocation(location.x, location.y); Object obj = null; if ((tp == null) || !((obj = tp.getLastPathComponent()) instanceof Node)) return null; /* JST: Is necessary? Cannot be overriden to use the * special Transferable? // accept only some data flavors if (!dtde.get isDataFlavorSupported(NodeTransfer.nodeCutFlavor) && !dtde.isDataFlavorSupported(NodeTransfer.nodeCopyFlavor) && !dtde.isDataFlavorSupported(ExTransferable.multiFlavor)) { return null; } */ // succeeded return tp; } /** Safe accessor to the drop target which is asociated * with the tree */ DropTarget getDropTarget () { if (dropTarget == null) { dropTarget = new DropTarget(tree, view.getAllowedDropActions(), this, false); } return dropTarget; } } /* end class TreeViewDropSupport */ /* * Log * 11 Gandalf 1.10 1/13/00 Ian Formanek NOI18N * 10 Gandalf 1.9 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 9 Gandalf 1.8 8/27/99 Jaroslav Tulach New threading model & * Children. * 8 Gandalf 1.7 6/30/99 Jaroslav Tulach Drag and drop support * 7 Gandalf 1.6 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 6 Gandalf 1.5 5/16/99 David Simonek debug prints commented * 5 Gandalf 1.4 4/30/99 David Simonek * 4 Gandalf 1.3 4/28/99 David Simonek drag and drop in tree now * supports multi-selection * 3 Gandalf 1.2 4/27/99 David Simonek autoscroll support and * visual feedback in DnD operations added * 2 Gandalf 1.1 4/22/99 David Simonek made non-public * 1 Gandalf 1.0 4/21/99 David Simonek * $ */